﻿using System;
using System.Linq;
using System.Numerics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using psieve;
using psieve.factor;
using psieve.sieve;

namespace psieveTest
{
    [TestClass]
    public class TestFactoring
    {
        private static readonly Random random = new Random();

        private static readonly IFactor trialDivision = new TrialDivision(new Eratosthenes());
        private static readonly IFactor fermat = new Fermat();

        private void Test(IFactor fac, BigInteger n)
        {
            Console.WriteLine("n: " + n);

            var expected = trialDivision.Factor(n).ToList();
            Console.WriteLine("expected factors: " + String.Join(",", expected));
            
            var actual = fac.Factor(n).ToList();
            Console.WriteLine("actual factors: " + String.Join(",", actual));

            Assert.IsTrue(expected.SequenceEqual(actual));
        }

        [TestMethod]
        public void TestTiny_Fermat()
        {
            Test(fermat, 3265289);
        }

        [TestMethod]
        public void TestRandTiny_Fermat()
        {
            Test(fermat, random.Next(2, int.MaxValue));
        }

        [TestMethod]
        public void TestRand_2x10_Fermat()
        {
            Test(fermat, Utils.GenerateProbablyPrimeByBits(10, 1) * Utils.GenerateProbablyPrimeByBits(10, 1));
        }

        [TestMethod]
        public void TestRand_2x25_Fermat()
        {
            Test(fermat, Utils.GenerateProbablyPrimeByBits(25, 1) * Utils.GenerateProbablyPrimeByBits(25, 1));
        }
    }
}
